package br.uefs.ecomp.myBook.util;

import static org.junit.Assert.*;

import java.util.Iterator;
import java.util.LinkedHashSet;

import org.junit.Before;
import org.junit.Test;

import br.uefs.ecomp.myBook.model.*;

public class IGraphTest {
	
	IGraph<Profile> graph;
	Profile p1, p2, p3, p4, p5;

	@Before
	public void setUp() throws Exception {
		graph = new Graph<>();
		p1 = new Profile("p1", "12345", "Joao", "null", "null", "Salvador"/*, "Precisa disso?"*/, "None");
		p2 = new Profile("p2", "12345", "Pedro", "null", "null", "Feira", /*"Precisa disso?",*/ "None");
		p3 = new Profile("p3", "12345", "Joao Pedro", "null", "null", "Feira da Mata", /*"Precisa disso?",*/ "None");
		p4 = new Profile("p4", "12345", "Maria Joao", "null", "null", "Feira de Santana", /*"Precisa disso?",*/ "None");
		p5 = new Profile("p5", "12345", "Marta MAria", "null", "null", "Feira", /*"Precisa disso?",*/ "None");
	}

	@Test
	public void testAdd() throws DataAlreadyExistsException {
		graph.add(p1);
		graph.add(p2);
		graph.add(p3);
		graph.add(p4);
	}
	
	@Test(expected=DataAlreadyExistsException.class)
	public void testAddRepeated() throws DataAlreadyExistsException{
		testAdd();
		graph.add(p1);
	}
	
	@Test
	public void testFind() throws DataNotFoundException, DataAlreadyExistsException {
		testAdd();
		assertEquals(graph.find("p1"), p1);
		assertEquals(graph.find("p2"), p2);
	}
	
	@Test(expected=DataNotFoundException.class)
	public void testFindException() throws DataNotFoundException, DataAlreadyExistsException{
		testAdd();
		graph.find("p5");
	}
	
	@Test
	public void testAddEdge() throws DataNotFoundException, DataAlreadyExistsException {
		testAdd();
		graph.addEdge(p1, p2);
		graph.addEdge("p2", "p3");
		graph.addEdge(p3, p4);
		graph.addEdge("p4", "p1");
	}
	
	@Test(expected=DataAlreadyExistsException.class)
	public void testAddEdgeException() throws DataNotFoundException, DataAlreadyExistsException{
		testAddEdge();
		graph.addEdge(p1, p2);
	}
	
	@Test
	public void testHasEdge() throws DataNotFoundException, DataAlreadyExistsException{
		testAddEdge();
		assertTrue(graph.hasEdge("p1", "p2"));
		assertFalse(graph.hasEdge("p1", "p3"));
	}
	
	@Test
	public void testDeleteEdge() throws DataNotFoundException, DataAlreadyExistsException{
		testAddEdge();
		assertTrue(graph.hasEdge("p1", "p2"));
		graph.removeEdge(p1, p2);
		assertFalse(graph.hasEdge("p1", "p2"));
	}
	
	@Test
	public void testGetNeighbors() throws DataNotFoundException, DataAlreadyExistsException {
		testAddEdge();
		LinkedHashSet<Profile> s = new LinkedHashSet<>();
		for(Profile p : graph.getNeighbors("p1")){
			s.add(p);
		}
		assertFalse(s.contains(p1));
		assertTrue(s.contains(p2));
		assertFalse(s.contains(p3));
		assertTrue(s.contains(p4));
		assertFalse(s.contains(p5));
	}

	@Test
	public void testSearch() throws DataNotFoundException, DataAlreadyExistsException {
		testAddEdge();
		Iterator<Profile> it = graph.search("Joao").iterator();
		Profile p = it.next();
		assertEquals(p1, p);
		p = it.next();
		assertEquals(p3, p);
		p = it.next();
		assertEquals(p4, p);
		p = it.next();
		assertNull(p);
	}

	@Test
	public void testBreadthSearch() throws DataNotFoundException, DataAlreadyExistsException{
		testAddEdge();
		Iterator<Profile> it = graph.search(p1, "Joao").iterator();
		Profile p = it.next();
		assertEquals(p1, p);
		p = it.next();
		assertEquals(p4, p);
		p = it.next();
		assertEquals(p3, p);
		p = it.next();
		assertNull(p);
	}
	
	@Test
	public void testBreadthSearch2() throws DataNotFoundException, DataAlreadyExistsException{
		testAddEdge();
		Iterator<Profile> it = graph.search(p1, "Joao\nFeira", Profile.SEARCH_NAME_CITY).iterator();
		Profile p = it.next();
		assertEquals(p4, p);
		p = it.next();
		assertEquals(p3, p);
		p = it.next();
		assertNull(p);
	}

}
